package cn.zshprint.serein.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.zshprint.serein.entity.RoleUserRelation;
import cn.zshprint.serein.exception.ServiceException;
import cn.zshprint.serein.service.RoleUserRelationService;
import cn.zshprint.serein.utils.PBKDF2Utils;
import cn.zshprint.serein.vo.LoginVO;
import cn.zshprint.serein.vo.UserRegisterVO;
import cn.zshprint.serein.vo.UserReturnVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zshprint.serein.entity.User;
import cn.zshprint.serein.service.UserService;
import cn.zshprint.serein.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * 用户服务impl
 *
 * @author zshprint
 * @date 2021/07/28
 */
@Service
@PropertySource("classpath:avatar.properties")
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {


    public static final String owner = "OWNER";
    public static final String admin = "ADMIN";

    @Resource
    private RoleUserRelationService roleUserRelationService;
    /**
     * 默认的头像url
     */
    @Value("${defaultAvatar}")
    private String defaultAvatar;

    /**
     * 注册
     *
     * @param userRegisterVO 用户注册签证官
     * @return {@link Integer}
     * @throws NoSuchAlgorithmException 没有这样的算法异常
     * @throws InvalidKeySpecException  无效的关键规范异常
     */
    @Override
    @Transactional
    public Integer register(UserRegisterVO userRegisterVO,String type) throws NoSuchAlgorithmException, InvalidKeySpecException {
        QueryWrapper<User> notDuplicate = new QueryWrapper<User>()
                .eq("username", userRegisterVO.getUsername());
        User notDuplicateUser = getOne(notDuplicate);
        if (notDuplicateUser != null) {
            throw new ServiceException("该用户已经注册", 501);
        }
        //密码处理
        String password = userRegisterVO.getPassword();
        String salt = PBKDF2Utils.generateSalt();
        String encryptedPassword = PBKDF2Utils.getEncryptedPassword(password, salt);
        User registerUser = new User()
                .setUsername(userRegisterVO.getUsername())
                .setNickname(userRegisterVO.getNickname())
                .setPassword(encryptedPassword)
                .setAvatar(defaultAvatar)
                .setSalt(salt);

        if (type != null) {
            if (admin.equals(type)) {
                registerUser.setNote("管理员");
            } else if (owner.equals(type)) {
                registerUser.setNote("店家");
            } else {
                throw new ServiceException("类型错误", -1);
            }
        } else {
            registerUser.setNote("普通用户");
        }
        registerUser.setCreateTime(LocalDateTime.now());
        save(registerUser);
        RoleUserRelation roleUserRelation = new RoleUserRelation();
        roleUserRelation.setUserId(registerUser.getId());
        if (type == null) {
            roleUserRelation.setRoleId(3);
            roleUserRelation.setDesc("该用户是普通用户，可以进行购买等常规操作");
        } else {
            if (admin.equals(type)) {
                roleUserRelation.setRoleId(5);
                roleUserRelation.setDesc("该用户是管理员，最高权限者");
            } else if (owner.equals(type)) {
                roleUserRelation.setRoleId(4);
                roleUserRelation.setDesc("该用户是店家，对商品进行操作");
            } else {
                throw new ServiceException("类型错误", -1);
            }
        }
        roleUserRelationService.save(roleUserRelation);
        return registerUser.getId();
    }

    /**
     * 更新用户
     *
     * @param user 用户
     * @return {@link User}
     */
    @Override
    public User updateUser(User user) {
        updateById(user);
        return getById(user.getId());
    }

    /**
     * 删除用户
     *
     * @param id id
     * @return {@link Integer}
     */
    @Override
    public Integer deleteUser(Integer id) {
        removeById(id);
        return id;
    }

    /**
     * 登录
     *
     * @param loginVO 登录签证官
     * @return {@link UserReturnVO}
     * @throws NoSuchAlgorithmException 没有这样的算法异常
     * @throws InvalidKeySpecException  无效的关键规范异常
     */
    @Override
    public UserReturnVO login(LoginVO loginVO) throws NoSuchAlgorithmException, InvalidKeySpecException {
        String username = loginVO.getUsername();
        String password = loginVO.getPassword();
        User userByName = getOne(new QueryWrapper<User>()
                .eq("username", username));
        if (userByName == null) {
            throw new ServiceException("该用户不存在", 502);
        }
        String salt = userByName.getSalt();
        boolean authenticate = PBKDF2Utils.authenticate(password, userByName.getPassword(), salt);
        if (authenticate) {
            userByName.setLoginTime(LocalDateTime.now());
            updateById(userByName);
            UserReturnVO userReturnVO = new UserReturnVO();
            BeanUtils.copyProperties(userByName,userReturnVO);
            return userReturnVO;
        } else {
            throw new ServiceException("用户名或密码错误", 503);
        }
    }

    /**
     * 得到一个用户名
     *
     * @param username 用户名
     * @return {@link UserReturnVO}
     */
    @Override
    public UserReturnVO getOneByUsername(String username) {
        User res = getOne(new QueryWrapper<User>()
                .eq("username", username));
        UserReturnVO userReturnVO = new UserReturnVO();
        BeanUtils.copyProperties(res, userReturnVO);
        return userReturnVO;
    }

    /**
     * 找到所有
     *
     * @return {@link List<UserReturnVO>}
     */
    @Override
    public List<UserReturnVO> findAll() {
        List<User> list = list();
        List<UserReturnVO> userReturnVOS = new ArrayList<>();
        for (User user : list) {
            UserReturnVO userReturnVO = new UserReturnVO();
            BeanUtils.copyProperties(user,userReturnVO);
            userReturnVOS.add(userReturnVO);
        }
        return userReturnVOS;
    }

    /**
     * 通过id获取一个
     *
     * @param id id
     * @return {@link UserReturnVO}
     */
    @Override
    public UserReturnVO getOneById(Integer id) {
        User byId = getById(id);
        UserReturnVO userReturnVO = new UserReturnVO();
        BeanUtils.copyProperties(byId,userReturnVO);
        return userReturnVO;
    }
}




